home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’91 / AliasThis! / AliasThisƒ / src / SampleAEvt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-09  |  19.5 KB  |  599 lines  |  [TEXT/MPS ]

  1. #include <Aliases.h>        /* for ResolveAlias in our coercion routine */
  2. #include <Script.h>            /* for GetMBarHeight */
  3. #include <GestaltEqu.h>
  4. #include <Errors.h>
  5.  
  6. #include "SampleDefs.h"
  7. #include "Sample.h"
  8. #include "SampleErrors.h"
  9. #include "SampleFileIO.h"
  10. #include "SampleMain.h"
  11. #include "SamplePrint.h"
  12. #include "SampleAEvt.h"
  13.  
  14.  
  15. struct pairs{
  16.     AEKeyword    theAEKeyWord;
  17.     long        theRefcon;
  18. };
  19. typedef struct pairs pairs;
  20. static pairs    keyWordsToInstall[] = { { kAEOpenApplication, kAEOpenApplication },
  21.                                         { kAEOpenDocuments, kAEOpenDocuments },
  22.                                         { kAEPrintDocuments, kAEPrintDocuments },
  23.                                         { kAEQuitApplication, kAEQuitApplication },
  24.                                         { kAEAnswer, kAEAnswer },
  25.                                         { traeEchoID, traeEchoID },
  26.                                         { traeMoveFrontWindowMsgID, traeMoveFrontWindowMsgID }};
  27.  
  28. #pragma segment Main
  29. /************************************************************************************
  30.  
  31.     InitAppleEvents
  32.  
  33.     Intialize our AppleEvent dispatcher table. For every pair of entries in
  34.     keyWordsToInstall, we make a call to AEInstallEventHandler(). We use a common
  35.     event dispatcher (called DispatchAppleEvent), which keys off of the refcon. So
  36.     we load the refcon with the event ID.
  37.  
  38.     We also install a coercion handler to convert aliases to FSSpecs.
  39.  
  40. *************************************************************************************/
  41. void InitAppleEvents(void)
  42. {
  43.     OSErr    err;
  44.     long    result;
  45.     short    i;
  46.  
  47.     gHasPPCToolbox = (Gestalt(gestaltPPCToolboxAttr, &result) ? false : result != 0);
  48.  
  49.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  50.  
  51.     if (gHasAppleEvents) {
  52.         for (i = 0; i < (sizeof(keyWordsToInstall) / sizeof(pairs)); ++i)
  53.             if ( err = AEInstallEventHandler(kCoreEventClass,
  54.                                             keyWordsToInstall[i].theAEKeyWord,
  55.                                             (ProcPtr) DispatchAppleEvent,
  56.                                             keyWordsToInstall[i].theRefcon,
  57.                                             false) ) {
  58.                 DisplayError(err, nil, "InitAppleEvents: Calling AEInstallEventHandler.");
  59.                 return;
  60.             };
  61.  
  62.         if (err = AEInstallCoercionHandler(typeAlias, typeFSS, (ProcPtr) CoerceAliasToFSS,
  63.                                               0L, true, false) ) {
  64.             DisplayError(err, nil, "InitAppleEvents: Trying to install CoerceAliasToFSS");
  65.             return;
  66.         };
  67.     };
  68.  
  69. }
  70.  
  71.  
  72. #pragma segment Main
  73. /**************************************************************************************
  74.  
  75.     CoerceAliasToFSS
  76.  
  77.     This is the routine used to convert aliases to FSSpecs. It is called by the
  78.     AppleEvent Manager whenever we ask for an FSSpec, but it only has aliases. It
  79.     is installed into the AppleEvent manager in InitAppleEvents() with a call to
  80.     AEInstallCoercionHandler().
  81.  
  82.     Actually, I think an 'alis' -> 'fss ' coercion handler is built into the
  83.     AppleEvent Manager, but this is still a good example of what to do.
  84.  
  85. ***************************************************************************************/
  86. pascal OSErr CoerceAliasToFSS(AEDesc theAEDesc, DescType toType,
  87.                                 long handlerRefcon, AEDesc *result)
  88. {
  89. #pragma unused (toType, handlerRefcon)
  90.  
  91.     OSErr        err;
  92.     FSSpec        target;
  93.     Boolean        wasChanged;
  94.  
  95.     err = ResolveAlias(nil, (AliasHandle) theAEDesc.dataHandle, &target, &wasChanged);
  96.     if (!err)
  97.         err = AECreateDesc(typeFSS, (Ptr) &target, sizeof(FSSpec), result);
  98.     return (err);
  99. }
  100.  
  101. #pragma segment Main
  102. /**************************************************************************************
  103.  
  104.     MakeTarget
  105.  
  106.     Creates a TargetID for use in the AECreateAppleEvent call. If sendDirect is
  107.     TRUE, the target is specified by setting a ProcessDerialNumber to
  108.     kCurrentProcess. This has the advantage of sending the message directly to
  109.     ourselves, by passing ePPC and gaining about a 10-15x speed improvement. If
  110.     sendDirect is FALSE, we see if we have the PPCToolBox. If not, then we are
  111.     forced to do a direct send. If we do have the PPCToolbox, then we call
  112.     PPCBrowser. We then look at the reply, and factor in the mode we are going to
  113.     use in AESend. If that mode is kAEWaitReply and the user selected us as the
  114.     target, we have to turn that into a direct send. This is because the
  115.     AppleEvent Manager will otherwise post the event as a high-level event.
  116.     However, we are busy waiting for a reply, not looking for events, so we'll
  117.     hang. We avoid this by forcing a direct send.
  118.  
  119. ***************************************************************************************/
  120. OSErr MakeTarget(AEAddressDesc *target, Boolean sendDirect, short replyMode)
  121. {
  122.     OSErr                err = 0;
  123.     ProcessSerialNumber targetPSN;
  124.     ProcessSerialNumber myPSN;
  125.     TargetID            theTargetID;
  126.     Boolean                sendingToSelf;
  127.  
  128.     if (!sendDirect) {
  129.         if (!gHasPPCToolbox) {
  130.             sendDirect = true;
  131.         }
  132.         else {
  133.             if (!(err = PPCBrowser(nil, nil, gDefaultOK, &gLocation, &gPortInfo, nil, nil))) {
  134.                 gDefaultOK = true;
  135.                 if (replyMode != kAEWaitReply) {
  136.                     sendDirect = false;
  137.                 }
  138.                 else {
  139.                     if (gLocation.locationKindSelector == 0) {        /* sending to this machine */
  140.                         GetCurrentProcess(&myPSN);
  141.                         if (err = GetProcessSerialNumberFromPortName(&gPortInfo.name, &targetPSN))
  142.                             DisplayError(err, nil, "MakeTarget: getting our process serial number.");
  143.                         else if (err = SameProcess(&targetPSN, &myPSN, &sendingToSelf))
  144.                             DisplayError(err, nil, "MakeTarget: error calling SameProcess.");
  145.                     }
  146.                     else        /* sending to some other machine, so it can't be us. */
  147.                         sendingToSelf = false;
  148.  
  149.                     if (sendingToSelf) {
  150.                         DisplayError(0, nil, "MakeTarget: Cannot send to yourself through ePPC when using WaitReply mode. Using direct send instead.");
  151.                         sendDirect = true;
  152.                     }
  153.                     else
  154.                         sendDirect = false;
  155.                 }
  156.             }
  157.         }
  158.     }
  159.  
  160.     if (!err) {
  161.         if (sendDirect) {
  162.             targetPSN.highLongOfPSN = 0;
  163.             targetPSN.lowLongOfPSN = kCurrentProcess;
  164.             err = AECreateDesc(typeProcessSerialNumber, (Ptr) &targetPSN, sizeof(targetPSN), target);
  165.             if (err)
  166.                 DisplayError(err, nil, "MakeTarget: creating descriptor for target (1).");
  167.         }
  168.         else {
  169.             theTargetID.location = gLocation;
  170.             theTargetID.name = gPortInfo.name;
  171.             err = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(theTargetID), target);
  172.             if (err)
  173.                 DisplayError(err, nil, "MakeTarget: creating descriptor for target (2).");
  174.         }
  175.     }
  176.     return (err);
  177. }
  178.  
  179.  
  180. #pragma segment Main
  181. /*************************************************************************************
  182.  
  183.     MyIdleProc
  184.  
  185.     This routine gets either an updateEvt, an activateEvt, a nullEvent or an
  186.     OSEvent. The first time called it will get a nullEvent; this is its chance to
  187.     set the sleep value and mouseRegion that will be passed to WaitNextEvent by
  188.     the caller within the AEM.  After that it will also get events of the other
  189.     types (which are lost if masked out by the AEM) and must do with them whatever
  190.     is appropriate.
  191.  
  192. **************************************************************************************/
  193. pascal Boolean MyIdleProc(EventRecord *event, long *sleepTime, RgnHandle *mouseRgn)
  194. {
  195.     switch (event->what) {
  196.  
  197.         case updateEvt:
  198.         case activateEvt:
  199.         case kOSEvent:
  200.  
  201.             /* These events are passed by the AppleEvent manager to avoid dropping while
  202.                waiting for a reply or notification. Every procedure should handle these
  203.                events in their idle procedure. In this code, we simply dispatch these
  204.                events back to the main event loop handling code. */
  205.  
  206.             AdjustCursor(event->where, gCursorRgn, false, 0);
  207.             DoEvent(event);
  208.             break;
  209.  
  210.  
  211.         case nullEvent:
  212.  
  213.             /* The idle procedure is called once with the null event before the loop
  214.                begins. This allows the application to alter sleep time and mouseRgn to meet
  215.                its own needs. Since we're doing nothing, set the cursor to a watch. */
  216.  
  217.             AdjustCursor(event->where, gCursorRgn, true, 'wait');
  218.  
  219.             *mouseRgn = gCursorRgn;
  220.             *sleepTime = 60;        /* This is just like the WaitNextEvent sleeptime, so
  221.                                       use the correct value for your application. It's
  222.                                       better to use a non-zero value here rather than zero,
  223.                                       as using zero really slows you down. */
  224.             /* DoIdle(); */            /* ... this is the applications idle handling */
  225.             break;
  226.  
  227.         default:
  228.             DebugStr("\Got an event.what I'm not set up to handle.");
  229.             break;
  230.     }
  231.     return(false);
  232. }
  233.  
  234.  
  235. #pragma segment Main
  236. /*************************************************************************************
  237.  
  238.     CreateAndSendAppleEvent
  239.  
  240.     Given an event ID, this routine creates such an event and posts it with
  241.     AESend. Right now, all we know about are our own MoveWindow events and Echo
  242.     events.
  243.  
  244. **************************************************************************************/
  245. void CreateAndSendAppleEvent(AEEventID whichAppleEvent)
  246. {
  247.  
  248. #define PRIORITY kAENormalPriority
  249.  
  250.     OSErr            err;
  251.     AppleEvent        theAevt;
  252.     AEAddressDesc    theTarget;
  253.     Point            thePoint;
  254.     short            i;
  255.     long            startTime;
  256.     AppleEvent        theReply;
  257.     short            offsetForTitleBar = GetMBarHeight() + 20; /* actually, it's bad form
  258.                                                                 to assume 20... */
  259.  
  260.     if (err = MakeTarget(&theTarget, gSendToSelf, gReplyMode)) {
  261.         if (err != userCanceledErr)
  262.             DisplayError(err, nil, "CreateAndSendAppleEvent: after MakeTarget.");
  263.     }
  264.     else {
  265.         switch (whichAppleEvent) {
  266.  
  267. /*
  268.     Create the Window moved event. This is just a random point passed to
  269.     the receiving application, which is expected to move the frontmost window
  270.     to that point.
  271. */
  272.  
  273.             case traeMoveFrontWindowMsgID:
  274.                 thePoint.h = Random() % (qd.screenBits.bounds.right-6) + 1;
  275.                 thePoint.v = Random() % (qd.screenBits.bounds.bottom-6-offsetForTitleBar) + offsetForTitleBar;
  276.  
  277.                 if ( thePoint.v < 0 )
  278.                     thePoint.v *= -1;
  279.  
  280.                 if ( thePoint.h < 0 )
  281.                     thePoint.h *= -1;
  282.  
  283.                 if (err = AECreateAppleEvent(kCoreEventClass, traeMoveFrontWindowMsgID, &theTarget,
  284.                             kAutoGenerateReturnID, kAnyTransactionID, &theAevt))
  285.                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AECreateAppleEvent.");
  286.  
  287.                 else if (err = AEPutParamPtr(&theAevt, keyDirectObject, typePoint, (Ptr) &thePoint, sizeof(Point)))
  288.                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AEPutParamPtr.");
  289.  
  290.                 else if (err = AESend(&theAevt, nil, kAENoReply, PRIORITY, 0, nil, nil)) {
  291.                     if (err == userCanceledErr)        /*    I hope this is right. The error
  292.                                                         used to be loginCancelErr, but
  293.                                                         that went away. */
  294.                         DisplayError(0, nil, "User Canceled logging on to destination computer.");
  295.                     else
  296.                         DisplayError(err, nil, "CreateAndSendAppleEvent: after AESend.");
  297.                 }
  298.  
  299.                 if (err = AEDisposeDesc(&theAevt))
  300.                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AEDisposeDesc of the AppleEvent.");
  301.                 break;
  302.  
  303.  
  304. /*
  305.     Create and send an 'echo' message to the receiving application 1000 times.
  306.     Clock the elapsed time, and display it when done.
  307. */
  308.  
  309.             case traeEchoID:
  310.                 if (err = AECreateAppleEvent(kCoreEventClass, traeEchoID, &theTarget,
  311.                             kAutoGenerateReturnID, kAnyTransactionID, &theAevt))
  312.                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AECreateAppleEvent.");
  313.  
  314.  
  315.                 else {
  316.  
  317.                     startTime = TickCount();
  318.  
  319.                     for (i=0; (i<1000) && !err; ++i) {
  320.  
  321.                         switch (gReplyMode) {
  322.  
  323.                             case kAENoReply:
  324.                                 if (err = AESend(&theAevt, nil,
  325.                                                 kAENoReply, PRIORITY,
  326.                                                 kNoTimeOut, nil, nil))
  327.                                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AESend.");
  328.                                 break;
  329.  
  330.                             case kAEWaitReply:
  331.                                 if (err = AESend(&theAevt, &theReply,
  332.                                                 kAEWaitReply, PRIORITY,
  333.                                                 kNoTimeOut, (IdleProcPtr) MyIdleProc, nil))
  334.                                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AESend.");
  335.                                 else if (err = AEDisposeDesc(&theReply))
  336.                                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AEDisposeDesc of the echo reply.");
  337.                                 break;
  338.  
  339.                             case kAEQueueReply:
  340.                                 if (err = AESend(&theAevt, &theReply,
  341.                                                 kAEQueueReply, PRIORITY,
  342.                                                 kNoTimeOut, nil, nil)) {
  343.                                     if (err == userCanceledErr)    /*    I hope this is right. The error
  344.                                                                     used to be loginCancelErr, but
  345.                                                                     that went away. */
  346.                                         DisplayError(0, nil, "User Canceled logging on to destination computer.");
  347.                                     else
  348.                                         DisplayError(err, nil, "CreateAndSendAppleEvent: after AESend.");
  349.                                 }
  350.                                 else if (err = AEDisposeDesc(&theReply))
  351.                                     DisplayError(err, nil, "CreateAndSendAppleEvent: after AEDisposeDesc of the echo reply.");
  352.                                 break;
  353.  
  354.                             default:
  355.                                 DisplayError(gReplyMode, nil, "CreateAndSendAppleEvent: gReplyMode set to an unknown value.");
  356.                                 break;
  357.  
  358.                         }
  359.                     }
  360.  
  361.                     ShowElapsedTime(TickCount() - startTime);
  362.  
  363.                     if (err = AEDisposeDesc(&theAevt))
  364.                         DisplayError(err, nil, "CreateAndSendAppleEvent: after AEDisposeDesc of the AppleEvent.");
  365.                 }
  366.                 break;
  367.  
  368. /*
  369.     Duh...I don't know, George!
  370. */
  371.  
  372.             default:
  373.                 DisplayError(0, nil, "CreateAndSendAppleEvent: asked to send an event I don't know.");
  374.                 break;
  375.         }  /* switch */
  376.  
  377. /*
  378.     We created a descriptor for the target address. Better get rid of it.
  379. */
  380.  
  381.     if (err = AEDisposeDesc(&theTarget))
  382.         DisplayError(err, nil, "CreateAndSendAppleEvent: after AEDisposeDesc of the target.");
  383.  
  384.     } /* if (error on MakeTarget) else ... */
  385. }
  386.  
  387.  
  388. #pragma segment Main
  389. /***************************************************************************************
  390.  
  391.     MoveTheFrontWindow
  392.  
  393.     Called when we recieve an AppleEvent with an ID of "traeMoveFrontWindowMsgID".
  394.     It takes the point that's passed in the AppleEvent, and uses it to reposition
  395.     the front window.
  396.  
  397. *****************************************************************************************/
  398. OSErr MoveTheFrontWindow(AppleEvent message, AppleEvent reply, long refcon)
  399. {
  400. #pragma unused (reply, refcon)
  401.  
  402.     DescType    actualType;
  403.     Point        pt;
  404.     long        actualSize;
  405.     WindowPtr    window = FrontWindow();
  406.     OSErr        err;
  407.     short        offsetForTitleBar = GetMBarHeight() + 20; /* actually, it's bad form to
  408.                                                              assume 20... */
  409.  
  410.     if ( IsAppWindow(window) ) {
  411.         if (err = AEGetParamPtr(&message, keyDirectObject, typePoint,
  412.                 &actualType, (Ptr) &pt, sizeof(Point), &actualSize))
  413.             DisplayError(err, nil, "MoveTheFrontWindow: after AEGetParamPtr.");
  414.         else {
  415.             if (pt.h > qd.screenBits.bounds.right-6)
  416.                 pt.h = qd.screenBits.bounds.right-6;
  417.             if (pt.v > qd.screenBits.bounds.bottom-6)
  418.                 pt.v = qd.screenBits.bounds.bottom-6;
  419.             else if (pt.v < offsetForTitleBar)
  420.                 pt.v = offsetForTitleBar;
  421.  
  422.             MoveWindow(window, pt.h, pt.v, true);
  423.         }
  424.         return (err);
  425.     } else
  426.         return (noErr);
  427. }
  428.  
  429.  
  430. #pragma segment Main
  431. /***************************************************************************************
  432.  
  433.     MissedAnyParameters
  434.  
  435.     Used to check for any unread required parameters. Returns true if we missed at
  436.     least one.
  437.  
  438. *****************************************************************************************/
  439. Boolean MissedAnyParameters(AppleEvent message)
  440. {
  441.     OSErr        err;
  442.     DescType    ignoredActualType;
  443.     AEKeyword    missedKeyword;
  444.     Size        ignoredActualSize;
  445.     EventRecord    event;
  446.  
  447.     err = AEGetAttributePtr(&message, keyMissedKeywordAttr, typeKeyword, &ignoredActualType,
  448.                             (Ptr) &missedKeyword, sizeof(missedKeyword), &ignoredActualSize);
  449.  
  450. /*    No error means that we found some more. */
  451.  
  452.     if (err == noErr) {
  453.         event.message = *(long *) &ignoredActualType;
  454.         event.where = *(Point *) &missedKeyword;
  455.         DisplayError(err, &event, "MissedAnyParameters: got parameters I don't know what to do with.");
  456.         err = errAEEventNotHandled;
  457.     }
  458.  
  459. /*
  460.     errAEDescNotFound means that there are no more parameters. If we get
  461.     an error code other than that, flag it.
  462. */
  463.  
  464.     else if (err != errAEDescNotFound) {
  465.         DisplayError(err, nil, "MissedAnyParameters: after AEGetAttributeDesc.");
  466.     }
  467.     
  468.     return (err != errAEDescNotFound);
  469. }
  470.  
  471.  
  472. #pragma segment Main
  473. /***************************************************************************************
  474.  
  475.     OpenDocEventHandler
  476.  
  477.     Called when we recieve an AppleEvent with an ID of "kAEOpenDocuments". This
  478.     routine gets the direct parameter, parses it up into little FSSpecs, and opens
  479.     each indicated file. It also shows the technique to be used in determining if
  480.     you are doing everything the AppleEvent record is telling you. Parameters can
  481.     be divided up into two groups: required and optional. Before executing an
  482.     event, you must make sure that you've read all the required events. This is
  483.     done by making an "any more?" call to the AppleEvent manager.
  484.  
  485. *****************************************************************************************/
  486. OSErr OpenDocEventHandler(AppleEvent message, AppleEvent reply, Boolean forPrinting)
  487. {
  488. #pragma unused (reply)
  489.  
  490.     OSErr        err;
  491.     OSErr        err2;
  492.     AEDesc        theDesc;
  493.     FSSpec        theFSS;
  494.     short        loopy;
  495.     long        numFilesToOpen;
  496.     AEKeyword    ignoredKeyWord;
  497.     DescType    ignoredType;
  498.     Size        ignoredSize;
  499.  
  500.     if (err = AEGetParamDesc(&message, keyDirectObject, typeAEList, &theDesc)) {
  501.         DisplayError(err, nil, "OpenDocEventHandler: after AEGetParamDesc.");
  502.         return(err);
  503.     }
  504.  
  505.     if (!MissedAnyParameters(message)) {
  506.  
  507. /*
  508.     Got all the parameters we need. Now, go through the direct object,
  509.     see what type it is, and parse it up.
  510. */
  511.         if (err = AECountItems(&theDesc, &numFilesToOpen))
  512.             DisplayError(err, nil, "OpenDocEventHandler: after AECountItems.");
  513.         else {
  514.             for (loopy = 1; ((loopy <= numFilesToOpen) && (!err)); ++loopy) {
  515.                 if (err = AEGetNthPtr(&theDesc, loopy, typeFSS, &ignoredKeyWord, &ignoredType,
  516.                                         (Ptr) &theFSS, sizeof(theFSS), &ignoredSize))
  517.                     DisplayError(err, nil, "OpenDocEventHandler: after AEGetNthDesc.");
  518.                 else {
  519.                     if (!forPrinting)
  520.                         err = OpenFile(&theFSS);
  521.                     else
  522.                         err = PrintFile(&theFSS);
  523.                 }
  524.             }    /* for loopy = ... */
  525.         }    /* AECountItems OK */
  526.     }    /* Got all necessary parameters */
  527.  
  528.     if (err2 = AEDisposeDesc(&theDesc))
  529.         DisplayError(err2, nil, "OpenDocEventHandler: after AEDisposeDesc of theDesc.");
  530.  
  531.     return(err ? err : err2);
  532. }
  533.  
  534.  
  535. #pragma segment Main
  536. /***************************************************************************************
  537.  
  538.     DispatchAppleEvent
  539.  
  540.     This routine is called by the AppleEvent manager to handle any events we
  541.     registered with it. Because we registered the event with the event ID in the
  542.     refcon, we can use the refcon in a switch statement. For each ID, we call to a
  543.     routine to handle the event.
  544.  
  545.     This is really just one way of dispatching AppleEvents. Its advantages are
  546.     that everything is in one place, and the code in InitAppleEventr used to set
  547.     it up is simple. The disadvantage is that we have to case on the event ID
  548.     number. The AppleEvent Manager already has to do this for us, so another way
  549.     to handle this is to simply install a different routine for each message
  550.     class/ID, and not use a case statement.
  551.  
  552. *****************************************************************************************/
  553. pascal OSErr DispatchAppleEvent(AppleEvent message, AppleEvent reply, long refcon)
  554. {
  555. #define kTimeOutInTicks (60 * 120)
  556.  
  557.     switch ( refcon ) {
  558.         case kAEOpenApplication:
  559.             return (OpenNewWindow());
  560.         case kAEOpenDocuments:
  561.             return (OpenDocEventHandler(message, reply, false));
  562.         case kAEPrintDocuments:
  563.             if (!AEInteractWithUser(kTimeOutInTicks, nil, (IdleProcPtr) MyIdleProc))
  564.                 PresentStyleDialog();
  565.             return (OpenDocEventHandler(message, reply, true));
  566.         case kAEQuitApplication:
  567.             Terminate();
  568.             return (noErr);
  569.         case kAEAnswer:
  570.             return (noErr);
  571.         case traeEchoID:
  572.             return (noErr);
  573.         case traeMoveFrontWindowMsgID:
  574.             return (MoveTheFrontWindow(message, reply, refcon));
  575.         default:
  576.             return (errAEEventNotHandled);
  577.     }
  578. }
  579.  
  580.  
  581. #pragma segment Main
  582. /***************************************************************************************
  583.  
  584.     DoHighLevelEvent
  585.  
  586.     Simply calls AEProcessAppleEvent and reports any errors. AEProcessAppleEvent
  587.     looks in its table of registered events and sees if the current event is
  588.     registered. If so, it calls the routine associated with that event. In our
  589.     case, we set that to DispatchAppleEvent.
  590.  
  591. *****************************************************************************************/
  592. void DoHighLevelEvent(EventRecord *event)
  593. {
  594.     OSErr        err;
  595.  
  596.     if ( err = AEProcessAppleEvent(event) )
  597.         DisplayError(err, event, "DoHighLevelEvent: After AEProcessAppleEvent");
  598. }
  599.